package hu.uszeged.inf.wlab.stunner.screens.bookmarks;

import hu.uszeged.inf.wlab.stunner.R;
import hu.uszeged.inf.wlab.stunner.database.dtos.DiscoveryDTO;
import hu.uszeged.inf.wlab.stunner.utils.Constants;

import java.text.MessageFormat;

import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;

import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;

/**
 * {@link Fragment} implementation which handles and displays the map and the markers.
 * 
 * @author szelezsant
 */
public class MapFragment extends Fragment {

	/** The padding used when zooming the camera. */
	private static final int ZOOM_PADDING = 25;

	/** The google maps view object. */
	private MapView mapView;
	/** The bounds builder. */
	private LatLngBounds.Builder boundsBuilder;

	@Override
	public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
		final View inflatedView = inflater.inflate(R.layout.fragment_map, container, false);
		mapView = (MapView) inflatedView.findViewById(R.id.mapView);
		mapView.onCreate(savedInstanceState);

		return inflatedView;
	}

	@Override
	public void onResume() {
		super.onResume();
		mapView.onResume();

		if (null != getArguments() && getArguments().containsKey(Constants.KEY_DATA)) {
			boundsBuilder = new LatLngBounds.Builder();
			for (final Parcelable discoveryParcel : getArguments().getParcelableArray(Constants.KEY_DATA)) {
				addMarker(discoveryParcel);
			}

			try {
				MapsInitializer.initialize(getActivity());
				/* animate to camera to display all of the markers */
				initMapPosition();
			} catch (final GooglePlayServicesNotAvailableException exception) {
				Log.e(getClass().getSimpleName(), "failed to initialize google maps: " + exception);
			}
		}
	}

	@Override
	public void onPause() {
		super.onPause();
		mapView.onPause();
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		mapView.onDestroy();
	}

	@Override
	public void onLowMemory() {
		super.onLowMemory();
		mapView.onLowMemory();
	}

	/**
	 * Creates a marker object from the argument and displays on the map.
	 * 
	 * @param discoveryParcel - the data source.
	 */
	private void addMarker(final Parcelable discoveryParcel) {
		final DiscoveryDTO discovery = (DiscoveryDTO) discoveryParcel;
		if (null != discovery) {
			final StringBuilder snippetBuilder = new StringBuilder();
			snippetBuilder.append(getString(discovery.getDiscoveryResult().getResourceId()) + "\n")
					.append(MessageFormat.format(getString(R.string.pattern_short_local_ip), discovery.getLocalIP()));
			final StringBuilder titleBuilder = new StringBuilder();
			titleBuilder.append(DateFormat.format(getString(R.string.date_format), discovery.getTimeStamp()).toString() + "\n")
					.append(discovery.getLocation());
			final LatLng location = new LatLng(discovery.getLatitude(), discovery.getLongitude());
			mapView.getMap().addMarker(new MarkerOptions().position(location)
					.title(titleBuilder.toString()).snippet(snippetBuilder.toString()));
			boundsBuilder.include(location);
		}
	}

	/**
	 * Initializes the map positions after the map is ready to operate.
	 */
	private void initMapPosition() {
		if (mapView.getViewTreeObserver().isAlive()) {
			mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

				// [szelezsant] checked conditions
				@SuppressWarnings("deprecation")
				@SuppressLint("NewApi")
				@Override
				public void onGlobalLayout() {
					if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
						mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
					} else {
						mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
					}
					mapView.getMap().animateCamera(CameraUpdateFactory.newLatLngBounds(boundsBuilder.build(), ZOOM_PADDING));
				}
			});
		}
	}
}
